package com.geekcode.guide;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;
import com.geekcode.guide.annotation.GuiMethod;
import com.geekcode.guide.annotation.GuiType;
import com.geekcode.guide.annotation.Param;

public class Guide {
	
	static Scanner scanner = new Scanner(System.in);
	
	public static void run(Class<?>... cs) throws Exception {
		System.out.println("请根据下列提示选择您所需要的操作");
		System.out.println();
		ArrayList<Class<?>> clazzs = new ArrayList<Class<?>>();
		for (Class<?> cla : cs) {
			GuiType type = cla.getAnnotation(GuiType.class);
			if(type == null) { continue; }
			System.out.println((clazzs.size() + 1) + ": " + type.name());
			clazzs.add(cla);
		}
		System.out.println("0: 退出");
		int i = -1;
		do {
			System.out.println();
			System.out.print("请选择：");
			i = scanner.nextInt();
		} while (i < 0 || i > clazzs.size());
		if(i == 0) { return; }
		System.out.println();
		run(clazzs.get(i - 1));
	}
	
	public static void run(Class<?> clazz) throws Exception {
		GuiType type = clazz.getAnnotation(GuiType.class);
		for (String msg : type.message()) {
			System.out.println(msg);
		}
		System.out.println();
		ArrayList<Method> methods = new ArrayList<Method>();
		for (Method m : clazz.getDeclaredMethods()) {
			GuiMethod guimethod = m.getAnnotation(GuiMethod.class);
			if(guimethod == null) { continue; }
			System.out.println((methods.size() + 1) + ": " + guimethod.name());
			methods.add(m);
		}
		System.out.println("0: 退出");
		int i = -1;
		do {
			System.out.println();
			System.out.print("请选择：");
			i = scanner.nextInt();
		} while (i < 0 || i > methods.size());
		System.out.println();
		if(i == 0) { return; }
		runMethod(clazz, methods.get(i - 1));
	}
	
	public static void runMethod(Class<?> clazz, Method m) throws Exception {
		GuiMethod ms = m.getAnnotation(GuiMethod.class);
		for (String msg : ms.message()) {
			System.out.println(msg);
		}
		Object[] args = new Object[m.getParameterCount()];
		if(m.getParameterCount() > 0) {
			Parameter[] parameters = m.getParameters();
			for (int i = 0; i < parameters.length; i++) {
				Parameter parameter = parameters[i];
				Param param = parameter.getAnnotation(Param.class);
				if(param == null) {
					System.out.print("请输入参数[" + parameter.getName() +"]：");
				}else {
					System.out.print(param.message()  +"：");
				}
				Class<?> pClass = parameter.getType();
				String p = scanner.next();
				args[i] = format(p, pClass);
			}
		}
		if(m.isSynthetic()) {
			m.invoke(null, args);
		}else{
			m.invoke(clazz.newInstance(), args);
		}
	}
	
	
	public static Object format(String value, Class<?> clazz) throws IllegalArgumentException, IllegalAccessException {
		if(clazz == boolean.class || clazz == Boolean.class){ 		return Boolean.valueOf(value); }
		else if(clazz == short.class || clazz == Short.class){ 		return Short.valueOf(value); }
		else if(clazz == int.class || clazz == Integer.class){ 		return Integer.valueOf(value); }
		else if(clazz == long.class || clazz == Long.class){ 		return Long.valueOf(value); }
		else if(clazz == double.class || clazz == Double.class){	return Double.valueOf(value); }
		else if(clazz == float.class || clazz == Float.class){ 		return Float.valueOf(value); }
		else if(clazz == BigInteger.class){ 						return new BigInteger(value); }
		else if(clazz == BigDecimal.class){ 						return new BigDecimal(value); }
		else if(clazz == byte.class || clazz == Byte.class){ 		return Byte.valueOf(value); }
		else if(clazz == byte[].class || clazz == Byte[].class){ 	return value.getBytes();}
		else{ return value;}
	}
}
